package cron

import (
	"fmt"
	"github.com/cihub/seelog"
	"github.com/robfig/cron"
	"io/ioutil"
	"irisysFtp/analysis"
	"irisysFtp/conf"
	"irisysFtp/db"
	"os"
	"strings"
	"time"
)

func RunFunc() {
	c := cron.New()
	myCron := conf.GetCron()
	c.AddFunc(myCron.ExectNotSuccessCron, func() {
		seelog.Infof("exect not success %v", myCron.ExectNotSuccessCron)
		exectNotSuccess()
	})
	c.AddFunc(myCron.DeleteFileCron, func() {
		seelog.Infof("delete file cron %v", myCron.DeleteFileCron)
		moveFile()
		//deleteFile()
		//checkFileCount(2000, 5)
	})
	c.Start()
	seelog.Infof("cron %+v", myCron)
}

func moveFile() {
	files, err := db.GetAllFile()
	if err != nil {
		seelog.Error(err)
	}
	seelog.Infof("delete File len:%v", len(files))
	for _, val := range files {
		wp := fmt.Sprintf("%v%v", conf.FtpConf().Dir, string(val.Value))
		exist := pathExist(wp)
		status := 1
		if exist {
			split := strings.Split(string(val.Key), "_")
			time, err := time.Parse("20060102150405", split[1])
			if err != nil {
				seelog.Error(err)
				continue
			}
			status = RenameFile(wp, time)
			seelog.Infof("delete file path: %v", wp)
		} else {
			seelog.Errorf("delete error file path  %v not exist", wp)
		}
		if status == 1 {
			db.DeleteFile(val)
		}
	}
}

func RenameFile(source string, fileTime time.Time) int {
	targetDir := fmt.Sprintf("%v/%v", conf.FtpConf().BackDir, fileTime.Format("20060102"))
	if !pathExist(targetDir) {
		err := os.MkdirAll(targetDir, os.ModePerm)
		if err != nil {
			seelog.Error(err)
			return 0
		}
	}
	split := strings.Split(source, "/")
	target := fmt.Sprintf("%v/%v", targetDir, split[len(split)-1])
	err := os.Rename(source, target)
	if err != nil {
		seelog.Error(err)
		return 0
	}
	return 1
}

func checkFileCount(maxCount, subTime int) {
	ftpConf := conf.FtpConf()
	fileInfl, err := ioutil.ReadDir(ftpConf.Dir)
	if err != nil {
		seelog.Error(err)
	} else {
		fileCount := len(fileInfl)
		if fileCount > maxCount {
			nt := time.Now()
			for _, file := range fileInfl {
				if !file.IsDir() {
					su := nt.Sub(file.ModTime()).Minutes()
					if su > float64(subTime) {
						seelog.Infof("checkFileCount %v %v", file.Name(), file.ModTime())
						removeFile(fmt.Sprintf("%v/%v", ftpConf.Dir, file.Name()))
					}
				}
			}
		}
	}
}

func exectNotSuccess() {
	flow, err := db.GetAllFlow()
	if err != nil {
		seelog.Error("exect not success error")
	}
	for _, val := range flow {
		if b := analysis.HttpClient(val.Value); b {
			db.DeleteFlow(val)
		} else {
			seelog.Errorf("error key %s val %s", val.Key, val.Value)
			split := strings.Split(string(val.Key), "_")
			parse, err := time.Parse("20060102150405", split[1])
			if err == nil {
				// 保存10天
				duration, _ := time.ParseDuration("-240h")
				if parse.Before(time.Now().Add(duration)) {
					db.DeleteFlow(val)
				}
			} else {
				seelog.Error(err)
			}
		}
	}
}

func deleteFile() {
	files, err := db.GetAllFile()
	if err != nil {
		seelog.Error(err)
	}
	seelog.Infof("delete File len:%v", len(files))
	for _, val := range files {
		wp := fmt.Sprintf("%v%v", conf.FtpConf().Dir, string(val.Value))
		exist := pathExist(wp)
		if exist {
			removeFile(wp)
			seelog.Infof("delete file path: %v", wp)
		} else {
			seelog.Errorf("delete error file path  %v not exist", wp)
		}
		db.DeleteFile(val)
	}
}

func removeFile(wp string) int {
	err := os.Remove(wp)
	if err == nil || os.IsNotExist(err) {
		return 1
	} else {
		seelog.Error(err.Error())
		return 0
	}
}
func pathExist(_path string) bool {
	_, err := os.Stat(_path)
	if err != nil && os.IsNotExist(err) {
		return false
	}
	return true
}
